#include "Epoll.h"
#include <sys/epoll.h>
#include <stdio.h>
#include <stdlib.h>
#include "TcpConnection.h"

#include <iostream>
using std::endl; using std::cout;

Epoll::Epoll()
:epollfd_(createEpollfd())
{}

int Epoll::createEpollfd()
{
    int fd = ::epoll_create(1024);
    if (-1 == fd)
    {
        perror("epollcreate err");
        exit(EXIT_FAILURE);
    }

    return fd;
}

void Epoll::loop()
{
    int count = epoll_wait(epollfd_, evs, maxcount, -1);
    if (-1 == count)
    {
        perror("epollwait err");
        return;
    }

    for (int i = 0; i < count; ++i)
    {
        epoll_event *cur_ev = &evs[i];
        TcpConnection *conn = (TcpConnection*)(cur_ev->data.ptr);
		conn->events = evs[i].events;
        //conn->printConnInfo();
        channels_[conn->sockfd_.fd()]->onMessCb_();
        /*
        switch (conn->socktype_)
        {
            case esock_listen:
            {
                int fd = ::accept(conn->sockfd_.fd(), NULL, NULL);
                cout << fd << endl;
            }
            break;

            default:
                break;
        }
        */
    }
}

void Epoll::epollAdd(int fd, void *pconn, shared_ptr<Channel> pchannel)
{
    struct epoll_event ev;
    ev.data.ptr = pconn;
    ev.events = EPOLLIN;
    if (-1 == epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &ev))
    {
        perror("epollctl add err");
        exit(EXIT_FAILURE);
    }
    channels_[fd] = pchannel;
}

void Epoll::epollDel(int fd)
{
    if (-1 == epoll_ctl(epollfd_, EPOLL_CTL_DEL, fd, NULL))
	{
		perror("epollctl del err");
		exit(EXIT_FAILURE);
	}
    channels_.erase(fd);
}

void Epoll::epollWrite(int fd, void *ud, bool enable)
{
    struct epoll_event ev;
    ev.events = EPOLLIN | (enable ? EPOLLOUT : 0);
    ev.data.ptr = ud;
    epoll_ctl(epollfd_, EPOLL_CTL_MOD, fd, &ev);
}

